package com.interview.customer.respository;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.EntityType;

import org.springframework.stereotype.Repository;

import com.interview.contacts.entity.Contacts;
import com.interview.contacts.entity.Contacts_;
import com.interview.contacts.query.ContactsConditionQuery;
import com.interview.core.page.Page;
import com.interview.customer.entity.Customer;
import com.interview.customer.entity.Customer_;
import com.interview.customer.query.CustomerConditionQuery;

@Repository
public class CustomerRespository {

	@PersistenceContext
	private EntityManager entityManager;

	public Customer save(Customer customer) {
		entityManager.persist(customer);
		return customer;
	}

	public Customer findOne(String id) {
		return entityManager.find(Customer.class, id);
	}

	public void delete(String id) {
		entityManager.remove(findOne(id));
	}

	public Customer update(Customer customer) {
		
		List<Contacts> contacts = customer.getContacts();
		String id = customer.getId();
		Customer customer2 = findOne(id);
		
		if (contacts == null || contacts.size() == 0) {

			customer2.getContacts().clear();
			customer2.setAddress(customer.getAddress());
			customer2.setDistrict(customer.getDistrict());
			customer2.setFax(customer.getFax());
			customer2.setLevel(customer.getLevel());
			customer2.setName(customer.getName());
			customer2.setTel(customer.getTel());

			return entityManager.merge(customer2);
			
		}else {
			
			return entityManager.merge(customer);
			
		}

		
	}

	public Page findByCustomersCustomerConditionQuery(
			CustomerConditionQuery conditionQuery) {

		String level = conditionQuery.getLevel();
		String name = conditionQuery.getName();
		String district = conditionQuery.getDistrict();
		Integer pageIndex = conditionQuery.getPageIndex();
		Integer pageSize = conditionQuery.getPageSize();

		if (name == "") {
			name = null;
		}

		if (name != null) {

			if (name.contains(" ")) {
				name = null;
			}
		}

		if (level.equals("All")) {
			level = null;
		}

		if (district.equals("All")) {
			district = null;
		}
		List<Predicate> predicates = new ArrayList<Predicate>();

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Customer> criteriaQuery = criteriaBuilder
				.createQuery(Customer.class);
		Root<Customer> root = criteriaQuery.from(Customer.class);

		if (name != null) {
			Predicate predicateName = criteriaBuilder.like(
					root.get(Customer_.name), "%" + name + "%");

			predicates.add(predicateName);
		}
		if (level != null) {
			Predicate predicateLevel = criteriaBuilder.equal(
					root.get(Customer_.level), level);

			predicates.add(predicateLevel);
		}

		if (district != null) {
			Predicate predicateDistrict = criteriaBuilder.equal(
					root.get(Customer_.district), district);

			predicates.add(predicateDistrict);
		}

		criteriaQuery.where(criteriaBuilder.and(predicates
				.toArray(new Predicate[predicates.size()])));

		Query query = entityManager.createQuery(criteriaQuery);
		Integer total = query.getResultList().size();

		if (pageIndex != 0) {
			query.setFirstResult(pageIndex * pageSize).setMaxResults(pageSize);
		} else {
			query.setFirstResult(0).setMaxResults(pageSize);
		}

		List<Customer> customers = query.getResultList();

		Page page = new Page();
		page.setList(customers);
		page.setPageIndex(pageIndex);
		page.setTotal(total);
		page.setTotal(total);

		return page;
	}

	public List<Customer> findAll() {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Customer> criteriaQuery = criteriaBuilder
				.createQuery(Customer.class);
		Root<Customer> root = criteriaQuery.from(Customer.class);

		List<Customer> customers = entityManager.createQuery(criteriaQuery)
				.getResultList();

		return customers;
	}

	// -----------------------------------------------------------------------------------

	public List<Contacts> findByCustomerId(String id) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Customer> criteriaQuery = criteriaBuilder
				.createQuery(Customer.class);
		Root<Customer> root = criteriaQuery.from(Customer.class);

		EntityType<Customer> entityType = root.getModel();

		@SuppressWarnings("unused")
		Join<Customer, Contacts> join = root.join(Customer_.contacts,
				JoinType.INNER);

		criteriaQuery.select(root);
		criteriaQuery.where(criteriaBuilder.equal(root.get(Customer_.id), id),
				criteriaBuilder.like(join.get(Contacts_.name), "%0000%"));

		TypedQuery typedQuery = entityManager.createQuery(criteriaQuery);

		List<Contacts> contacts = typedQuery.getResultList();

		return contacts;
	}

}
